package cn.feng.thinkInJava.a9_2_泛型.generics.a15_10_03;

//: generics/Wildcards.java
// Exploring the meaning of wildcards.
import cn.feng.thinkInJava.a9_2_泛型.generics.a15_10_01.*;

/**
 * 编译器何时才会关注原生类型和涉及无界通配符的类型之间的差异
 * 
 * @author fengyu
 * @date 2015年8月13日
 */// 示例使用了Holder<T>类,它包含接受Holder作为参数的各种方法,但是它们具有不同的形式,作为原生类型,具有具体类型参数以及具有无界通配符参数
public class Wildcards
{
	// Raw argument:
	static void rawArgs(Holder holder,Object arg)
	{
		// holder.set(arg); // Warning:
		// Unchecked call to set(T) as a
		// member of the raw type Holder
		// holder.set(new Wildcards()); // Same warning
		// Can't do this; don't have any 'T':
		// T t = holder.get();
		// OK, but type information has been lost:
		Object obj=holder.get();
	}
	
	// Similar to rawArgs(), but errors instead of warnings:
	static void unboundedArg(Holder<?> holder,Object arg)
	{
		// holder.set(arg); // Error:
		// set(capture of ?) in Holder<capture of ?>
		// cannot be applied to (Object)
		// holder.set(new Wildcards()); // Same error
		// Can't do this; don't have any 'T':
		// T t = holder.get();
		// OK, but type information has been lost:
		Object obj=holder.get();
	}
	
	static <T> T exact1(Holder<T> holder)
	{
		T t=holder.get();
		return t;
	}
	
	static <T> T exact2(Holder<T> holder,T arg)
	{
		holder.set(arg);
		T t=holder.get();
		return t;
	}
	
	static <T> T wildSubtype(Holder<? extends T> holder,T arg)
	{
		// holder.set(arg); // Error:
		// set(capture of ? extends T) in
		// Holder<capture of ? extends T>
		// cannot be applied to (T)
		T t=holder.get();
		return t;
	}
	
	static <T> void wildSupertype(Holder<? super T> holder,T arg)
	{
		holder.set(arg);
		// T t = holder.get(); // Error:
		// Incompatible types: found Object, required T
		// OK, but type information has been lost:
		Object obj=holder.get();
	}
	
	public static void main(String[] args)
	{
		Holder raw=new Holder<Long>();
		// Or:
		raw=new Holder();
		Holder<Long> qualified=new Holder<Long>();
		Holder<?> unbounded=new Holder<Long>();
		Holder<? extends Long> bounded=new Holder<Long>();
		Long lng=1L;
		rawArgs(raw,lng);
		rawArgs(qualified,lng);
		rawArgs(unbounded,lng);
		rawArgs(bounded,lng);
		unboundedArg(raw,lng);
		unboundedArg(qualified,lng);
		unboundedArg(unbounded,lng);
		unboundedArg(bounded,lng);
		// Object r1 = exact1(raw); // Warnings:
		// Unchecked conversion from Holder to Holder<T>
		// Unchecked method invocation: exact1(Holder<T>)
		// is applied to (Holder)
		Long r2=exact1(qualified);
		Object r3=exact1(unbounded); // Must return Object
		Long r4=exact1(bounded);
		// Long r5 = exact2(raw, lng); // Warnings:
		// Unchecked conversion from Holder to Holder<Long>
		// Unchecked method invocation: exact2(Holder<T>,T)
		// is applied to (Holder,Long)
		Long r6=exact2(qualified,lng);
		// Long r7 = exact2(unbounded, lng); // Error:
		// exact2(Holder<T>,T) cannot be applied to
		// (Holder<capture of ?>,Long)
		// Long r8 = exact2(bounded, lng); // Error:
		// exact2(Holder<T>,T) cannot be applied
		// to (Holder<capture of ? extends Long>,Long)
		// Long r9 = wildSubtype(raw, lng); // Warnings:
		// Unchecked conversion from Holder
		// to Holder<? extends Long>
		// Unchecked method invocation:
		// wildSubtype(Holder<? extends T>,T) is
		// applied to (Holder,Long)
		Long r10=wildSubtype(qualified,lng);
		// OK, but can only return Object:
		// Object r11 = wildSubtype(unbounded, lng);
		Long r12=wildSubtype(bounded,lng);
		// wildSupertype(raw, lng); // Warnings:
		// Unchecked conversion from Holder
		// to Holder<? super Long>
		// Unchecked method invocation:
		// wildSupertype(Holder<? super T>,T)
		// is applied to (Holder,Long)
		wildSupertype(qualified,lng);
		// wildSupertype(unbounded, lng); // Error:
		// wildSupertype(Holder<? super T>,T) cannot be
		// applied to (Holder<capture of ?>,Long)
		// wildSupertype(bounded, lng); // Error:
		// wildSupertype(Holder<? super T>,T) cannot be
		// applied to (Holder<capture of ? extends Long>,Long)
	}
} /// :~
